/**
 ******************************************************************************
 * @file    main.c
 * @author  Earlybird
 * @version V1.0.0
 * @date    30-May-2022
 * @brief   分割bin文件为指定大小文件
 ******************************************************************************
 * @attention
 *
 * Copyright (c) 2022 INESA(Group)Co., Ltd. R&D Center.
 * All rights reserved.
 *
 ******************************************************************************
 */

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <Windows.h>

#define RUNERROR  -1
#define RUNSUCESS 0

int cut_bin_file(char* file_addr, int file_cut_size) {
	/* 读取bin文件类型校验 */
	if (!strstr(file_addr, ".bin")) {
		printf("file type incorrect, please input proper bin file.");
		return RUNERROR;
	}

	/* 要求分割块大小校验 */
	if (!file_cut_size) {
		printf("file cut size incorrect, please input the size greater than 0.");
		return RUNERROR;
	}

	/* 读取2进制bin文件 */
	FILE* fp_bin = fopen(file_addr, "rb");
	if (!fp_bin) {
		perror("fopen bin file error");
		return RUNERROR;
	}

	/* 计算bin文件总大小 */
	int file_all_size = 0;
	fseek(fp_bin, 0, SEEK_END);
	file_all_size = ftell(fp_bin);

	/* 计算分割后文件个数 */
	int file_cut_num = 0;
	file_cut_num = (file_all_size % file_cut_size) ? (file_all_size / file_cut_size) + 1 : (file_all_size / file_cut_size);

	printf("bin file size: %dB, cut file size: %dB, cut file num: %d.\n", file_all_size, file_cut_size, file_cut_num);

	/* 生成分割后新文件 */
	fseek(fp_bin, 0, SEEK_SET);

	char* file_fifo = (char*)malloc(sizeof(char) * file_cut_size); // 定义分割文件缓冲区
	char* file_cut_addr = (char*)malloc(strlen(file_addr) - 4 + 4 + 10); //定义分割文件存放地址
	char* file_name = (char*)malloc(strlen(file_addr));

	strncpy(file_name, file_addr, strlen(file_addr) - 4); // 读取源文件存放地址及名称
	file_name[strlen(file_addr) - 4] = 0;

	int file_cut_cnt = 0;
	size_t file_read_size = 0;

	while (1) {
		memset(file_fifo, 0, file_cut_size);
		file_read_size = fread(file_fifo, 1, file_cut_size, fp_bin);

		if (!file_read_size) {
			printf("cut bin file done.\n");
			break;
		}

		file_cut_cnt++;

		sprintf(file_cut_addr, "%s_%003d.bin", file_name, file_cut_cnt); // 生成分割文件存放地址
		FILE* fp_cut_bin = fopen(file_cut_addr, "wb");
		if (!fp_cut_bin) {
			perror("create cut file error");
			return RUNERROR;
		}
		fwrite(file_fifo, 1, file_read_size, fp_cut_bin); //写入字节数是读出来的返回值
		printf("%s, size: %zdB, create done.\n", file_cut_addr, file_read_size);
		fclose(fp_cut_bin);
	}

	fclose(fp_bin);
	free(file_fifo);
	file_fifo = NULL;
	free(file_cut_addr);
	file_cut_addr = NULL;
	free(file_name);
	file_name = NULL;
	return RUNSUCESS;
}

int main(int argc, char** argv) {
	if (argc == 3) {
		cut_bin_file(argv[1], atoi(argv[2]));
	} else {
		printf("command format: cutbin.exe [file_name.bin] [cut_size]\n");
	}

	system("pause");
	return EXIT_SUCCESS;
}
